package gui;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import model.ProcessType;
import model.Stack;
import service.LocationNotFoundException;
import service.Service;

/**
 * @author Alexander Shidlovsky
 */
public class StackInfoDialog extends JDialog {
	private Stack stack;
	private JLabel lblName, lblTrays, lblCurrentProcess, lblNextProcess,
			lblWarning, lblCurrentLocation;
	private JTextField txfName, txfTrays, txfCurrentProcess, txfNextProcess;
	private JButton btnShowTasks, btnContinue, btnEdit;
	private JPanel contentPane = new JPanel();
	private CustomActionListener actionListener = new CustomActionListener();

	public StackInfoDialog(Stack stack) {
		setContentPane(contentPane);
		getContentPane().setLayout(null);

		setTitle("Stack info");
		setResizable(false);
		// setModal(true);

		setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		this.stack = stack;

		setLocation(50, 200);
		setSize(400, 300);

		lblName = new JLabel("Name");
		lblTrays = new JLabel("Number of trays");
		lblCurrentProcess = new JLabel("Current process");
		lblNextProcess = new JLabel("Next process");

		txfName = new JTextField(stack.getProductType().getName());
		txfTrays = new JTextField(Integer.toString(stack.getNumberOfTrays()));
		txfCurrentProcess = new JTextField(stack.getCurrentProcess()
				.getProcess().getName());
		txfNextProcess = new JTextField(stack.getNextProcess() != null ? stack
				.getNextProcess().getProcess().getName() : "No process");

		txfName.setEditable(false);
		txfTrays.setEditable(false);
		txfCurrentProcess.setEditable(false);
		txfNextProcess.setEditable(false);

		lblName.setSize(180, 20);
		lblTrays.setSize(180, 20);
		lblCurrentProcess.setSize(180, 20);
		lblNextProcess.setSize(180, 20);
		txfName.setSize(180, 20);
		txfTrays.setSize(180, 20);
		txfCurrentProcess.setSize(180, 20);
		txfNextProcess.setSize(180, 20);

		lblName.setLocation(20, 20);
		lblTrays.setLocation(20, 50);
		lblCurrentProcess.setLocation(20, 80);
		lblNextProcess.setLocation(20, 110);
		txfName.setLocation(190, 20);
		txfTrays.setLocation(190, 50);
		txfCurrentProcess.setLocation(190, 80);
		txfNextProcess.setLocation(190, 110);

		lblWarning = new JLabel();
		lblWarning.setLocation(20, 140);
		lblWarning.setSize(350, 50);

		long past = System.currentTimeMillis()
				- stack.getCurrentProcess().getStartTime().getTime();

		if (past < stack.getCurrentProcess().getProcess().getMinTime()) {
			lblWarning
					.setText("<html>Be careful! The running time of this process has not reached a minimum time yet! Passed: "
							+ Service.getInstance().milisToTime(past)
							+ "; Minimum time: "
							+ Service.getInstance().milisToTime(
									stack.getCurrentProcess().getProcess()
											.getMinTime()) + "</html>");
		} else if ((past >= stack.getCurrentProcess().getProcess().getMinTime())
				&& (past <= stack.getCurrentProcess().getProcess().getMaxTime())) {
			lblWarning
					.setText("<html>It is safe to run the next process now! Passed: "
							+ Service.getInstance().milisToTime(past)
							+ "; Minimum time: "
							+ Service.getInstance().milisToTime(
									stack.getCurrentProcess().getProcess()
											.getMinTime())
							+ "; Maximum time: "
							+ Service.getInstance().milisToTime(
									stack.getCurrentProcess().getProcess()
											.getMaxTime()) + "</html>");
		} else {
			lblWarning
					.setText("<html>That's too late to run the next process :( The stack will move to wastes. Passed: "
							+ Service.getInstance().milisToTime(past)
							+ "; Maximum time: "
							+ Service.getInstance().milisToTime(
									stack.getCurrentProcess().getProcess()
											.getMaxTime()) + "</html>");
		}

		lblWarning.setForeground(Color.RED);

		contentPane.add(lblName);
		contentPane.add(lblTrays);
		contentPane.add(lblCurrentProcess);
		contentPane.add(lblNextProcess);
		contentPane.add(txfName);
		contentPane.add(txfTrays);
		contentPane.add(txfCurrentProcess);
		contentPane.add(txfNextProcess);
		contentPane.add(lblWarning);

		btnShowTasks = new JButton("Show tasks");
		btnShowTasks.setBounds(10, 220, 89, 23);

		btnContinue = new JButton("Continue with next process");
		btnContinue.setBounds(190, 220, 180, 23);

		btnShowTasks.addActionListener(actionListener);
		btnContinue.addActionListener(actionListener);

		contentPane.add(btnShowTasks);
		contentPane.add(btnContinue);

		btnEdit = new JButton("Edit");
		btnEdit.setBounds(111, 220, 67, 23);
		contentPane.add(btnEdit);
		btnEdit.addActionListener(actionListener);

		if (stack.isWasted()) {
			btnContinue.setEnabled(false);
			btnEdit.setEnabled(false);
			lblCurrentProcess.setText("Failed process");
			lblNextProcess.setText("Failed at");
			txfNextProcess.setText(Service.getInstance().displayTime(
					stack.getCurrentProcess().getFinishTime()));
			lblWarning.setText("This stack is wasted.");
		} else if (stack.isFinished()) {
			btnContinue.setEnabled(false);
			btnEdit.setEnabled(false);
			lblWarning.setText("This stack is finished.");
		}

		if (stack.getLocation() != null) {
			lblCurrentLocation = new JLabel("Location: "
					+ stack.getLocation().toString());
			lblCurrentLocation.setBounds(20, 170, 350, 50);
			add(lblCurrentLocation);
		} else if (stack.getNextProcess() != null
				&& stack.getNextProcess().getProcess().getProcessType()
						.equals(ProcessType.IN_STOCK)) {
			String location = null;
			try {
				location = Service.getInstance().findFreeLocation().toString();
			} catch (LocationNotFoundException e) {
				location = "There is no location available";
			}
			lblCurrentLocation = new JLabel("Location: " + location);
			lblCurrentLocation.setBounds(20, 170, 350, 50);
			add(lblCurrentLocation);
		}
	}

	public void updateStackInfo() {
		txfTrays.setText(Integer.toString(stack.getNumberOfTrays()));
	}

	private class CustomActionListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == btnContinue) {
				try {
					Service.getInstance().nextProcess(stack);
					StackInfoDialog.this.dispose();
				} catch (LocationNotFoundException e1) {
					JOptionPane.showMessageDialog(StackInfoDialog.this,
							"Could not find location", "Error",
							JOptionPane.ERROR_MESSAGE);
				}
			} else if (e.getSource() == btnShowTasks) {
				TaskListDialog tlDialog = new TaskListDialog(
						StackInfoDialog.this.stack);
				tlDialog.setVisible(true);
			} else if (e.getSource() == btnEdit) {
				EditStack es = new EditStack(StackInfoDialog.this,
						StackInfoDialog.this.stack);
				es.setVisible(true);
			}
		}
	}
}
